package cn.youframe.sample.code;

import cn.youframe.frame.base.BaseServiceImpl;
import cn.youframe.frame.beans.TableInfoVO;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.List;

/**
 * User: Administrator
 * DateTime: 13-2-17: 下午12:15
 */
public class CodeServiceImpl extends BaseServiceImpl implements CodeService {
    private CodeDao codeDao;

    public CodeDao getCodeDao() {
        return codeDao;
    }

    public void setCodeDao(CodeDao codeDao) {
        this.codeDao = codeDao;
    }

    /**
     * genEntity
     *
     * @param tableName String
     * @param pakg String
     * @param charset String
     * @return String
     */
    public String genEntity(String tableName, String pakg,String charset){
        String retStr="";
        String[] colnames; // 列名数组
        String[] colTypes; // 列名类型数组
        String[] colMemos; // 列备注
        boolean f_util = false; // 是否需要导入包java.util.*
        boolean f_sql = false; // 是否需要导入包java.sql.*
        try{
            List<TableInfoVO> infoList=codeDao.getTableInfo(tableName);
            if(infoList!=null && infoList.size()>0){
                int isize=infoList.size();
                colnames = new String[isize];
                colTypes = new String[isize];
                colMemos = new String[isize];
                int idx=0;
                for(TableInfoVO tinfo:infoList){
                    colnames[idx]=tinfo.getColumnName();
                    if(tinfo.getDataScale()>0){
                        colTypes[idx]="float";
                    }else{
                        colTypes[idx]=tinfo.getDataType();
                    }
                    colMemos[idx]=tinfo.getComments();
                    if (tinfo.getDataType().equalsIgnoreCase("date")) {
                        f_util = true;
                    }else if (tinfo.getDataType().equalsIgnoreCase("clob") || tinfo.getDataType().equalsIgnoreCase("blob")) {
                        f_sql = true;
                    }
                    idx++;
                }
                String content=parse(colnames,colTypes,colMemos,f_util,f_sql,tableName,pakg);
                try {
                    String voFileName=builderName(tableName)+"VO.java";
                    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(voFileName),charset);
                    PrintWriter pw = new PrintWriter(osw);
                    pw.println(content);
                    pw.flush();
                    pw.close();
                    retStr="生成VO文件位置:"+System.getProperty("user.dir")+"/"+voFileName;
                } catch (IOException ioe) {
                    retStr="生成文件异常："+ioe.getMessage();
                    logger.error(ioe.getMessage(),ioe);
                }
            }else{
                retStr="表信息不存在";
                logger.error("表信息不存在！"+tableName);
            }
        }catch(Exception e){
            retStr="生成文件异常："+e.getMessage();
            logger.error(e.getMessage(),e);
        }
        return retStr;
    }
    /**
     * 解析处理(生成实体类主体代码)
     */
    private String parse(String[] colNames, String[] colTypes,String[] colMemos,boolean f_util,boolean f_sql,String filename,String pakg) {
        StringBuffer sb = new StringBuffer();
        sb.append("package ").append(pakg).append(";\r\n");
        sb.append("import cn.youframe.frame.beans.BaseVO;\r\n");
        if (f_util) {
            sb.append("import java.util.Date;\r\n");
        }
        if (f_sql) {
            sb.append("import java.sql.*;\r\n\r\n\r\n");
        }
        sb.append("public class ").append(builderName(filename)).append("VO extends BaseVO {\r\n");
        processAllAttrs(sb,colNames,colTypes,colMemos);
        processAllMethod(sb,colNames,colTypes);
        sb.append("}\r\n");
        return sb.toString();

    }

    /**
     * 生成所有的方法
     *
     * @param sb
     */
    private void processAllMethod(StringBuffer sb,String[] colnames, String[] colTypes) {
        for (int i = 0; i < colnames.length; i++) {
            sb.append("\tpublic void set").append(builderName(colnames[i])).append("(").append(sqlType2JavaType(colTypes[i])).append(" ").append(coderName(colnames[i])).append("){\r\n");
            sb.append("\t\tthis.").append(coderName(colnames[i])).append("=").append(coderName(colnames[i])).append( ";\r\n");
            sb.append("\t}\r\n");
            sb.append("\tpublic ").append(sqlType2JavaType(colTypes[i])).append(" get").append(builderName(colnames[i])).append("(){\r\n");
            sb.append("\t\treturn ").append(coderName(colnames[i])).append(";\r\n");
            sb.append("\t}\r\n");
        }
    }

    /**
     * 解析输出属性
     *
     * @return
     */
    private void processAllAttrs(StringBuffer sb,String[] colNames, String[] colTypes,String[] colMemos) {
        for (int i = 0; i < colNames.length; i++) {
            sb.append("\tprivate ").append(sqlType2JavaType(colTypes[i])).append(" ").append(coderName(colNames[i]));
            sb.append("; //").append(colMemos[i]).append("\r\n");

        }
    }

    private String sqlType2JavaType(String sqlType) {
        if (sqlType.equalsIgnoreCase("bit")) {
            return "bool";
        } else if (sqlType.equalsIgnoreCase("tinyint")) {
            return "byte";
        } else if (sqlType.equalsIgnoreCase("smallint")) {
            return "short";
        } else if (sqlType.equalsIgnoreCase("int")|| sqlType.equalsIgnoreCase("number")) {
            return "int";
        } else if (sqlType.equalsIgnoreCase("bigint")) {
            return "long";
        } else if (sqlType.equalsIgnoreCase("float")) {
            return "float";
        } else if (sqlType.equalsIgnoreCase("decimal")
                || sqlType.equalsIgnoreCase("numeric")) {
            return "double";
        } else if (sqlType.equalsIgnoreCase("money")
                || sqlType.equalsIgnoreCase("smallmoney")) {
            return "double";
        } else if (sqlType.equalsIgnoreCase("varchar2")
                || sqlType.equalsIgnoreCase("varchar")
                || sqlType.equalsIgnoreCase("char")
                || sqlType.equalsIgnoreCase("nvarchar")
                || sqlType.equalsIgnoreCase("nchar")) {
            return "String";
        } else if (sqlType.equalsIgnoreCase("datetime")||sqlType.equalsIgnoreCase("date")) {
            return "Date";
        }

        else if (sqlType.equalsIgnoreCase("blob")) {
            return "Blob";
        } else if (sqlType.equalsIgnoreCase("clob")) {
            return "Clob";
        }
        return null;
    }
    /**
     * 去除下划线 返回首字母大写字符串
     * @param name 名称
     * @return String
     */
    private String builderName(String name) {
        if (name==null || name.trim().equalsIgnoreCase(""))
            return "";
        StringBuffer temp = new StringBuffer();
        String[] str = name.split("_");
        if (str.length == 1) {
            temp.append(str[0].substring(0, 1).toUpperCase() + str[0].substring(1).toLowerCase());
        } else {
            for (int i=0; i<str.length; i++) {
                temp.append(str[i].substring(0, 1).toUpperCase());
                temp.append(str[i].substring(1).toLowerCase());
            }
        }
        String result = temp.toString();
        return result;
    }

    /**
     * 去除下划线 返回首字母小写字符串
     * @param name 名称
     * @return String
     */
    private String coderName(String name) {
        if (name==null || name.trim().equalsIgnoreCase(""))
            return "";
        StringBuffer temp = new StringBuffer();
        String[] str = name.split("_");
        if (str.length == 1) {
            temp.append(str[0].substring(0, 1).toUpperCase() + str[0].substring(1).toLowerCase());
        } else {
            for (int i=0; i<str.length; i++) {
                temp.append(str[i].substring(0, 1).toUpperCase());
                temp.append(str[i].substring(1).toLowerCase());
            }
        }
        String result = temp.toString();
        result = result.substring(0, 1).toLowerCase() + result.substring(1);
        return result;
    }

}
